package repository

import (
	"fmt"
	"invitation/internal/repository/cache"
	"sync"

	"gorm.io/gorm"
)

type Repository interface {
	GetDB() *gorm.DB
	IsRepository()
}

type CachedRepository interface {
	Repository
	CachedRepository()
}

type BaseRepository struct {
	db *gorm.DB
}

type BaseCachedRepository struct {
	repo     Repository
	cache    *cache.LRU
	repoName string
	mutex    sync.Mutex
}

func (bcr *BaseRepository) IsRepository() {}
func newBaseRepository(db *gorm.DB) *BaseRepository {
	return &BaseRepository{
		db: db,
	}
}
func (bcr *BaseCachedRepository) IsRepository()     {}
func (bcr *BaseCachedRepository) CachedRepository() {}
func newBaseCachedRepository(repo Repository, cache *cache.LRU, repoName string) *BaseCachedRepository {
	return &BaseCachedRepository{
		repo:     repo,
		cache:    cache,
		repoName: repoName,
	}
}

func (br *BaseRepository) GetDB() *gorm.DB {
	return br.db
}

func (bcr *BaseCachedRepository) GetDB() *gorm.DB {
	return bcr.repo.GetDB()
}

func (bcr *BaseCachedRepository) GetCache() *cache.LRU {
	return bcr.cache
}

func (bcr *BaseCachedRepository) GetBaseRepo() Repository {
	return bcr.repo
}

func (bcr *BaseCachedRepository) GenerateCacheKey(prefix string, args ...interface{}) string {
	key := bcr.repoName + "_" + prefix
	for _, arg := range args {
		key += "_" + fmt.Sprintf("%v", arg)
	}
	return key
}
